package cxydmmszl.chapter05.t081;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.HashSet;

/**
 * <li style="color: red;">Prob</li>
 * 判断数组中是否所有数字只出现过一次
 * <li style="color: green;">Desc</li>
 * 给定一个数字 arr，判断数组 arr 中是否所有的数字都只出现过一次。
 * <li style="color: green;">Input</li>
 * 输入包括两行，第一行一个整数 n(1≤n≤10^5)，代表数组 arr 的长度。
 * 第二行包括 n 个整数，代表数组 arr(1≤arr[i]≤10^7)。
 * <li style="color: green;">Output</li>
 * 如果arr中所有数字都只出现一次，输出“YES”，否则输出“NO”。
 * <li style="color: green;">PS</li>
 * 要求<br/>
 * 1.时间复杂度 O（n）。<br/>
 * 2.额外空间复杂度 O（1）。<br/>
 * <li style="color: blue;">Link</li> CD103
 *
 * @author habitplus
 * @since 2021-09-08 14:53
 */
public class Main {
    private static final StreamTokenizer st =
            new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

    private static int nextInt() {
        try {
            st.nextToken();
            return (int) st.nval;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return 0;
    }

    public static void main(String[] args) {

        int n = nextInt();
        int[] arr = new int[n];

        for (int i = 0; i < n; i++) {
            arr[i] = nextInt();
        }
        boolean ans = isUnique2(arr);
        System.out.println(ans ? "YES" : "NO");
    }

    /*
        哈希
     */
    private static boolean isUnique1(int[] arr) {
        if (arr == null || arr.length == 0) {
            return false;
        }
        HashSet<Integer> set = new HashSet<>();
        for (int e : arr) {
            if (set.contains(e)) return false;
            set.add(e);
        }
        return true;
    }

    /*
        堆
     */
    private static boolean isUnique2(int[] arr) {
        if (arr == null || arr.length == 0) {
            return false;
        }

        heapSort(arr);

        for (int i = 1; i < arr.length; i++) {
            if (arr[i - 1] == arr[i]) {
                return false;
            }
        }
        return true;
    }

    private static void heapSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        int n = arr.length;
        // 建堆
        for (int i = 1; i < n; i++) {
            heapInsert(arr, i);
        }

        // 依次取出堆中的元素
        for (int i = n - 1; i > 0; i--) {
            swap(arr, 0, i);
            heapify(arr, 0, i);
        }
    }

    private static void heapify(int[] arr, int k, int n) {
        int lch = 2 * k + 1, rch = 2 * k + 2;
        int largest = k;
        while (lch < n) {
            // 比较左孩子
            if (arr[lch] > arr[k]) largest = lch;

            // 比较右孩子
            if (rch < n && arr[rch] > arr[largest]) largest = rch;

            // 本次无需交换，说明堆已经调整好了
            if (largest == k) break;

            swap(arr, k, largest);
            k = largest;
            lch = 2 * k + 1;
            rch = 2 * k + 2;
        }
    }

    private static void heapInsert(int[] arr, int k) {
        // 大顶堆
        int p;
        while (k > 0) {
            p = (k - 1) / 2;
            if (arr[p] < arr[k]) {
                swap(arr, p, k);
                k = p;
            } else {
                break;
            }
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}

